#include "daemon_runner.h"
#include "daemon_process.h"
#include "thirdparty/log.h"
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
#include <assert.h>
#include <sys/reboot.h> //重启系统函数

#define DAEMON_COUNT 2  //子进程数量
//判断要重启的标志为
static int yes_restart = 0;
//判断不重启的标志为
static int no_restart = 0;
//错误创建的文件
#define ERROR_FILE "/tmp/gateway.error"

static DaemonProcess subprocesses[DAEMON_COUNT];   //子进程对象族
static int running = 1;                            //为1 正常运行 0 关闭所以子进程 


void signal_handler(int agv)
{
    running = 0;  //想要停止所有进程
}


void daemon_runner_run()
{
    //注册信号
    signal(SIGTERM,signal_handler);
    //把当前进程变成守护进程
    //daemon 参数1   0表示把工作目录改到根目录  1不改
    //daemon 参数2   0表示关闭标准输入  标准输出 标准错误   1不管
    if(daemon(0,1) < 0)
    {
        og_error("Daemonize failed");
        exit(EXIT_FAILURE);
    }
    //手动关闭标准输入 输出 错误
    close(STDIN_FILENO);  //关闭标准输入
    close(STDOUT_FILENO); //关闭标准输出
    close(STDERR_FILENO); //关闭标准错误

    //把标准输出和错误  从定向到"/var/log/gateway.log"

    //把标准输入 从定向到 一个null文件  确保不会获取到输入
    int stdin_fd =  open("/dev/null",O_RDWR); //打开一个文件 stdin_fd文将的fd  文件描述符
    if(stdin_fd != -1)
    {
        //把"/dev/null" 这个文将的文件描述符复制到这个进程的标准输入 
        //后面有标准输入就冲那个文件获取
        dup2(stdin_fd,STDIN_FILENO);   //标准输入冲定义到stdin_fd 这个文件   相当于把/dev/null这个文件作为这个进程的标准输入
        close(stdin_fd);  // 关闭临时文件描述符
    }

    int stdio_fd = open(LOG_FILE,O_RDWR|O_CREAT,0644);
    if(stdio_fd != -1)
    {
        dup2(stdio_fd,STDOUT_FILENO);
        close(stdio_fd);
    }

     int stdeer_fd = open(LOG_FILE,O_RDWR|O_CREAT,0644);
    if(stdeer_fd != -1)
    {
        dup2(stdeer_fd,STDERR_FILENO);
        close(stdeer_fd);
    }

    //初始化子进程app pta
    daemon_process_init(subprocesses,"app");
    daemon_process_init(subprocesses + 1,"ota");

    //启动子进程 定时查看
   while(running)
   {
     for(int i = 0 ; i < DAEMON_COUNT;i++)
    {
       if(daemon_process_start(subprocesses + i) == 0)
            {
                //表示重新创建了一个子线程层  正常来说应该自会有2次就算等于0
                //一个连续超过10次  一共两个子线程就算失败要进行重启
                yes_restart++;
            }
            else
            {
                //这里就算返回-1  表示子进层在运行 当no_restart等于2表示在正常运行
                no_restart++;
            }

            //判断是否重启 DAEMON_COUNT子线程数量  每个连续重启10 就是20  表示失败要重启
            if(yes_restart >= DAEMON_COUNT * 10)
            {
                //创建一个错误文件并且重启系统
                while(1)
                {
                    if(fopen(ERROR_FILE,"w") == 0)
                    {
                        //创建或打开成功
                        //重启操作系统脚本会更新
                        reboot(RB_AUTOBOOT);
                    }
                }
            }
            //判断no_restart是否等于子线层  如果等于表示所以子线层都正常运行yes_restart清o
            if(no_restart = DAEMON_COUNT)
            {
                //正常运行    清除标志位
                yes_restart = 0;
                no_restart = 0;  
            }
    }
    sleep(100);
   }
    //停止所有进程
    for(int i = 0 ; i < DAEMON_COUNT;i++)
    {
        daemon_process_stop(subprocesses + i);
        daemon_process_free(subprocesses + i);
    }
}

